package com.example.application.views.store;
import com.example.application.bean.PageBean;
import com.example.application.bean.ResultBean;
import com.example.application.bean.Store;

import com.example.application.bean.User;
import com.example.application.views.util.MyHttpClientUtil;
import com.example.application.views.util.ShowAllInfosUtil;
import com.example.application.views.util.DialogUtil;
import com.example.application.views.util.VerifyUtil;
import com.example.page.PageComponent;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vaadin.flow.component.*;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.splitlayout.SplitLayout;
import com.vaadin.flow.data.binder.BeanValidationBinder;

import com.vaadin.flow.data.converter.StringToDoubleConverter;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.PageTitle;
import com.example.application.views.main.MainView;
import com.vaadin.flow.component.dependency.CssImport;
import elemental.json.Json;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Label;

import java.util.*;

import com.vaadin.flow.component.textfield.TextField;
import java.nio.charset.StandardCharsets;


import org.springframework.web.util.UriUtils;
import com.vaadin.flow.component.upload.Upload;
import java.io.ByteArrayOutputStream;

@Route(value = "store", layout = MainView.class)
@PageTitle("门店管理")
@CssImport("./views/门店管理/门店管理-view.css")
public class StoreView extends Div {

    private Grid<Store> grid = new Grid<>(Store.class, false);

    private ObjectMapper mapper = new ObjectMapper();

    private Upload image;
    private Image imagePreview;
    private TextField name;
    private TextField corporation;
    private TextField telNum;
    private TextField licenseNum;
    private TextField address;
    private TextField city;
    private TextField clerkAttri;
    private TextField feature;
    private ComboBox<String> vipLevel;
    private TextField commissionRate;

    private int curPage = 1;
    private int pageSize = 2;
    private int tolNum;
    private int tolPage;

    private Button cancel = new Button("取消");
    private Button save = new Button("保存");
    private Dialog dialog = new Dialog();
    private Button delete = new Button("删除");
    private Button update = new Button("更新");
    private Button showGoods = new Button("查看商品");
    private Button showService = new Button("查看服务");

    private BeanValidationBinder<Store> binder;

    private Store store;

    private User user;

    public StoreView() {
        user = (User) UI.getCurrent().getSession().getAttribute("user");
        if (user == null){

        }else if("门店管理员".equals(user.getIdentity()) || "平台管理员".equals(user.getIdentity())){
            this.init();
        }else{
            DialogUtil.adminAuthority();
        }
    }

    private void createEditorLayout(SplitLayout splitLayout) {
        Div editorLayoutDiv = new Div();
        editorLayoutDiv.setId("editor-layout");

        Div editorDiv = new Div();
        editorDiv.setId("editor");
        editorLayoutDiv.add(editorDiv);

        FormLayout formLayout = new FormLayout();
        Label imageLabel = new Label("Image");
        imagePreview = new Image();
        imagePreview.setWidth("100%");
        image = new Upload();
        image.getStyle().set("box-sizing", "border-box");
        image.getElement().appendChild(imagePreview.getElement());
        name = new TextField("店名");
        corporation = new TextField("法人");
        telNum = new TextField("电话");
        licenseNum = new TextField("营业执照号码");
        address = new TextField("地址");
        city = new TextField("城市");
        clerkAttri = new TextField("店员");
        feature = new TextField("特色");
        vipLevel = new ComboBox<>("VIP等级");
        vipLevel.setItems(new String[]{"黄金", "白金", "钻石"});
        commissionRate = new TextField("佣金比例");
        Component[] fields = new Component[]{imageLabel, image, name, corporation, telNum, licenseNum, address, city, clerkAttri, feature, vipLevel, commissionRate};

        for (Component field : fields) {
            ((HasStyle) field).addClassName("full-width");
        }
        formLayout.add(fields);
        editorDiv.add(formLayout);
        createButtonLayout(editorLayoutDiv);

        splitLayout.addToSecondary(editorLayoutDiv);
    }

    private void createButtonLayout(Div editorLayoutDiv) {
        HorizontalLayout buttonLayout = new HorizontalLayout();
        buttonLayout.setId("button-layout");
        buttonLayout.setWidthFull();
        buttonLayout.setSpacing(true);
        cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
        save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        delete.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        update.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        showGoods.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        showService.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        buttonLayout.add(save, delete, update, cancel, showGoods, showService);
        editorLayoutDiv.add(buttonLayout);
    }

    private void createGridLayout(SplitLayout splitLayout) {
        Div wrapper = new Div();
        wrapper.setId("grid-wrapper");
        wrapper.setWidthFull();
        PageComponent pageComponent = new PageComponent(curPage, pageSize, StoreView.this.tolNum, StoreView.this.tolPage) {
            /**
             * 下一页
             */
            @Override
            protected void pageNext() {
                StoreView.this.curPage = this.curPage;
//                发送请求
                updateForm();
//                刷新
                init();
            }

            /**
             * 上一页
             */
            @Override
            protected void pagePrevious() {
                StoreView.this.curPage = this.curPage;
                updateForm();
                init();
//                发送请求

            }

            /**
             * 跳转目标页数
             */
            @Override
            protected void gotoPage() {

            }

            /**
             * 第一页
             */
            @Override
            protected void firstPage() {
                StoreView.this.curPage = 1;
                updateForm();
                init();
            }

            /**
             * 最后一页
             */
            @Override
            protected void lastPage() {
                StoreView.this.curPage = this.tolPage;

                updateForm();

                init();
            }

            /**
             * 选择每页显示条数
             */
            @Override
            protected void selectPage() {

            }
        };
        pageComponent.components.add(grid);
        pageComponent.init();
        splitLayout.addToPrimary(pageComponent);
    }

    private void attachImageUpload(Upload upload, Image preview) {
        ByteArrayOutputStream uploadBuffer = new ByteArrayOutputStream();
        upload.setAcceptedFileTypes("image/*");
        upload.setReceiver((fileName, mimeType) -> {
            return uploadBuffer;
        });
        upload.addSucceededListener(e -> {
            String mimeType = e.getMIMEType();
            String base64ImageData = Base64.getEncoder().encodeToString(uploadBuffer.toByteArray());
            String dataUrl = "data:" + mimeType + ";base64,"
                    + UriUtils.encodeQuery(base64ImageData, StandardCharsets.UTF_8);
            upload.getElement().setPropertyJson("files", Json.createArray());
            preview.setSrc(dataUrl);
            uploadBuffer.reset();
        });
        preview.setVisible(false);
    }

    private void refreshGrid() {
        grid.select(null);
        grid.getDataProvider().refreshAll();
    }

    private void clearForm() {
        populateForm(null);
    }

    private void populateForm(Store value) {
        this.store = value;
        binder.readBean(this.store);
    }

    private void updateForm(){
        ResultBean<PageBean> resultBean = ShowAllInfosUtil.showInfos(StoreUrl.STORE_QUERYPAGING, curPage, pageSize, Store.class);


        grid.setItems(resultBean.getT().getDatas());

        tolNum = resultBean.getT().getTolNum();

        tolPage = resultBean.getT().getTolPage();
    }

    public void init(){
        addClassName("门店管理-view");
        // Create UI
        SplitLayout splitLayout = new SplitLayout();
        splitLayout.setSizeFull();

        updateForm();
        createGridLayout(splitLayout);
        createEditorLayout(splitLayout);

        add(splitLayout);

        // Configure Grid
//        TemplateRenderer<SampleFoodProduct> imageRenderer = TemplateRenderer.<SampleFoodProduct>of(
//                "<span style='border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; width: 64px; height: 64px'><img style='max-width: 100%' src='[[item.image]]' /></span>")
//                .withProperty("image", SampleFoodProduct::getImage);
//        grid.addColumn(imageRenderer).setHeader("Image").setWidth("96px").setFlexGrow(0);

        grid.addColumn("name").setHeader("店名").setAutoWidth(true);
        grid.addColumn("corporation").setHeader("法人").setAutoWidth(true);
        grid.addColumn("telNum").setHeader("联系电话").setAutoWidth(true);
        grid.addColumn("licenseNum").setHeader("营业执照号码").setAutoWidth(true);
//        grid.addColumn("state").setAutoWidth(true);
//        grid.getColumnByKey("state").setHeader("商户状态");
        grid.addColumn("address").setHeader("营业地址").setAutoWidth(true);
        grid.addColumn("city").setHeader("城市").setAutoWidth(true);
        grid.addColumn("clerkAttri").setHeader("店员").setAutoWidth(true);
        grid.addColumn("feature").setHeader("特色").setAutoWidth(true);
        grid.addColumn("vipLevel").setHeader("VIP等级").setAutoWidth(true);
        grid.addColumn("commissionRate").setHeader("佣金比例").setAutoWidth(true);

        grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
        grid.setHeightFull();

        // when a row is selected or deselected, populate form
        grid.asSingleSelect().addValueChangeListener(event -> {
            populateForm(event.getValue());
        });

        // Configure Form
        binder = new BeanValidationBinder<>(Store.class);

        // Bind fields. This where you'd define e.g. validation rules
        binder.forField(commissionRate).withConverter(new StringToDoubleConverter("请输入数字")).bind("commissionRate");
        binder.bindInstanceFields(this);

        attachImageUpload(image, imagePreview);

        /**
         * 取消操作
         */
        cancel.addClickListener(e -> {
            clearForm();
            refreshGrid();
        });

        /**
         * 添加按钮
         */
        save.addClickListener(e -> {
//
            if(store!=null){
                try{
                    store.setName(name.getValue().trim());
                    store.setCorporation(corporation.getValue().trim());
                    store.setTelNum(telNum.getValue().trim());
                    store.setLicenseNum(licenseNum.getValue().trim());
                    store.setAddress(address.getValue().trim());
                    store.setCity(city.getValue().trim());
                    store.setClerkAttri(clerkAttri.getValue().trim());
                    store.setFeature(feature.getValue().trim());
                    store.setVipLevel(vipLevel.getValue().trim());
                    store.setCommissionRate(Double.parseDouble(commissionRate.getValue()));

                    if(VerifyInfo(store)){
                        String msg = MyHttpClientUtil.httpPost(StoreUrl.STORE_ADD, store, "utf-8");

                        ObjectMapper mapper = new ObjectMapper();

                        JavaType javaType = mapper.getTypeFactory().constructParametricType(ResultBean.class, String.class);

                        ResultBean<Store> storeResultBean = mapper.readValue(msg,javaType);

                        if(storeResultBean.getCode()==0){
                            UI.getCurrent().getPage().executeJs("alert('添加失败')");
                        }else{
                            UI.getCurrent().getPage().executeJs("alert('添加成功');window.location.href='http://localhost:8080/store'");
                        }
                    }
                } catch (Exception exception){
                    exception.printStackTrace();
                }
            }else{
                UI.getCurrent().getPage().executeJs("alert('请先输入数据!')");
            }

        });

        /**
         * 更新按钮
         */

        update.addClickListener(e -> {
            if(store!=null){
                try{
                    store.setName(name.getValue().trim());
                    store.setCorporation(corporation.getValue().trim());
                    store.setTelNum(telNum.getValue().trim());
                    store.setLicenseNum(licenseNum.getValue().trim());
                    store.setAddress(address.getValue().trim());
                    store.setCity(city.getValue().trim());
                    store.setClerkAttri(clerkAttri.getValue().trim());
                    store.setFeature(feature.getValue().trim());
                    store.setVipLevel(vipLevel.getValue().trim());
                    store.setCommissionRate(Double.parseDouble(commissionRate.getValue()));

                    if(this.VerifyInfo(store)){
                        String msg = MyHttpClientUtil.httpPut(StoreUrl.STORE_UPDATE, store, "utf-8");

                        ObjectMapper mapper = new ObjectMapper();

                        JavaType javaType = mapper.getTypeFactory().constructParametricType(ResultBean.class, String.class);

                        ResultBean<Store> storeResultBean = mapper.readValue(msg,javaType);

                        if(storeResultBean.getCode()==0){
                            UI.getCurrent().getPage().executeJs("alert('更新失败')");
                        }else{
                            UI.getCurrent().getPage().executeJs("alert('更新成功');window.location.href='http://localhost:8080/store'");

                        }
                    }
                }catch (Exception exception){
                    exception.printStackTrace();
                }
            }else{
                UI.getCurrent().getPage().executeJs("alert('你还没有要更新的数据!')");
            }
        });


        /**
         * 删除按钮
         */
        delete.addClickListener(e -> {
            Dialog dialog = new Dialog();
            dialog.setCloseOnEsc(false);
            dialog.setCloseOnOutsideClick(false);
            dialog.removeAll();
            dialog.add(new Text("确定要删除吗？"));

            Button okBtn = new Button("确定", sure ->{
//            执行删除操作
                if(store.getId()!=null){
                    String json = MyHttpClientUtil.httpDelete(StoreUrl.STORE_DELETE, store.getId(), "utf-8");

                    ResultBean deleteResult = null;
                    try {
                        deleteResult = mapper.readValue(json, ResultBean.class);
                    } catch (JsonProcessingException jsonProcessingException) {
                        jsonProcessingException.printStackTrace();
                    }
                    if(deleteResult.getCode() == 1){
                        UI.getCurrent().getPage().executeJs("alert('删除成功');window.location.href='http://localhost:8080/store'");
                    }else {
                        UI.getCurrent().getPage().executeJs("alert('删除失败');");
                    }
                    updateForm();
                }else{
                    UI.getCurrent().getPage().executeJs("alert('请先选择一条需要删除的数据');");

                }
                dialog.close();
            });

            Button noBtn = new Button("取消",e2->{
                dialog.close();
            });

            dialog.add(new Div(okBtn, new Text("      "), noBtn));
            dialog.open();

//            UI.getCurrent().getPage().executeJs("window.location.href='http://localhost:8080/store'");

        });

//        查看服务
        showService.addClickListener(e->{
            if(store == null){
                UI.getCurrent().getPage().executeJs("alert('请先选择商店');");
            }else if(!"门店管理员".equals(user.getIdentity())){
                UI.getCurrent().getPage().executeJs("alert('该功能只有门店管理员才能进行操作');");
            }else{
                UI.getCurrent().getSession().setAttribute("store", store);
                UI.getCurrent().navigate("supServer");
            }
        });

        // 查看商品
        showGoods.addClickListener(e->{
            if(store == null){
                UI.getCurrent().getPage().executeJs("alert('请先选择商店');");
            }else if(!"门店管理员".equals(user.getIdentity())){
                UI.getCurrent().getPage().executeJs("alert('该功能只有门店管理员才能进行操作');");
            }else{
                UI.getCurrent().getSession().setAttribute("store", store);
                UI.getCurrent().navigate("stoGoods");
            }
        });
    }

    public boolean VerifyInfo(Store store){
        if(!VerifyUtil.lengthVerify(store.getName())){
            UI.getCurrent().getPage().executeJs("alert('店名长度不能超过10');");
            return false;
        }else if(!VerifyUtil.lengthVerify(store.getCorporation())){
            UI.getCurrent().getPage().executeJs("alert('法人姓名不能超过10');");
            return false;
        }else if(!VerifyUtil.telePhoneNumVerify(store.getTelNum())){
            UI.getCurrent().getPage().executeJs("alert('电话格式错误');");
            return false;
        }else if(!VerifyUtil.licenseVerify(store.getLicenseNum())){
            UI.getCurrent().getPage().executeJs("alert('营业执照格式错误（17位数字+1位字母）');");
            return false;
        }else if(!VerifyUtil.clerkAttriVerify(store.getClerkAttri())){
            UI.getCurrent().getPage().executeJs("alert('店员人数不能超过10人（格式 数字 + 人）');");
            return false;
        }else if(!VerifyUtil.commissionRateVerify(store.getCommissionRate()+"")){
            UI.getCurrent().getPage().executeJs("alert('佣金格式错误');");
            return false;
        }else{
            return true;
        }
    }
}
